package com.gold.common.filters;

import com.gold.common.CacheUtils;
import com.gold.common.JsonUtils;
import com.gold.common.StringUtils;
import com.gold.common.TokenUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * @author XiaoHao
 * @date 2022-05-07 16:39
 */
public class TokenAuthFilter extends BasicAuthenticationFilter {


    public TokenAuthFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //如果是登录和注册直接放行请求
        String servletPath = request.getServletPath();
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();
        if ("/login".equals(servletPath)||"/register".equals(servletPath)||"/active".equals(servletPath)){
            response.reset();
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
            filterChain.doFilter(request, response);
        }
        //其他请求则判断token有效性
        String token = request.getHeader("Token");

        if (token != null && token != "") {
            //判断Token是否在黑名单中
            if (!CacheUtils.compareList(token)) {
                //验证token是否生效
                String verify = TokenUtil.verify(token);
                if (StringUtils.isNotEmpty(verify)){
                    out.write(JsonUtils.responseJson(false,JsonUtils.ERROR,verify,"").toJSONString());
                    out.flush();
                    out.close();
                }else {
                    String name = TokenUtil.getTokenName(token);
                    if (name != null && name != "") {
                        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                        if (authentication == null) {
                            List<GrantedAuthority> tokenRole = TokenUtil.getTokenRole(token);
                            SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(name, "", tokenRole));
                        }
                        response.reset();
                        response.addHeader("Access-Control-Allow-Origin", "*");
                        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
                        response.addHeader("Access-Control-Allow-Headers", "Content-Type");
                        filterChain.doFilter(request, response);
                    }
                }
            }else {
                //存在黑名单中  验证token是否生效
                String verify = TokenUtil.verify(token);
                if (StringUtils.isNotEmpty(verify)){
                    //失效 清除黑名单中的token
                    CacheUtils.removeList(token);
                }
            }


        }
        out.write(JsonUtils.responseJson(false,JsonUtils.ERROR,"您没有权限访问","").toJSONString());
        out.flush();
        out.close();
    }
}
